﻿namespace HiMap.MapControls
{
    using HiMap.Carto;
    using HiMap.Geometry;
    using HiMap.MapControls.Tools.Frm;
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Reflection;
    using System.Windows.Forms;

    internal class EditEnvironmentClass : IEditEnvironment
    {
        private IPoint _GPSPoint;
        private IFeature _isEditFeature;
        private IFeatureLayer _Layer;
        private Point _Location;
        private State _state;
        private ComboBox cmbPoints;
        private DrawControl draw;
        private IFeature Feat;
        private bool isMouseDown;
        private Panel MainPan;
        private PicCtrl MePic;
        private MapControl OperationMap;
        private Form ParentForm;
        private List<object> Propertys;
        private int StaX;
        private int StaY;

        internal EditEnvironmentClass(Form frm, MapControl Map)
        {
            this.ParentForm = frm;
            this.OperationMap = Map;
            this.Propertys = new List<object>();
            this.CreateControls();
            List<IPoint> mapPoints = new List<IPoint>();
            List<Point> points = new List<Point>();
            this.MePic = new PicCtrl(Map, mapPoints, points, PicType.Null);
            this._Location = new Point(0, 0);
        }

        private void BtnClick(object sender, EventArgs e)
        {
            PictureBox box = (PictureBox) sender;
            switch (box.Name)
            {
                case "picInsert":
                    if (this.cmbPoints.SelectedIndex == -1)
                    {
                        break;
                    }
                    this.OnAddPoint(this.cmbPoints.SelectedIndex);
                    return;

                case "picDelete":
                    if (this.cmbPoints.SelectedIndex == -1)
                    {
                        break;
                    }
                    this.OnDeletePoint(this.cmbPoints.SelectedIndex);
                    return;

                case "picGotoXY":
                    if (this.cmbPoints.SelectedIndex == -1)
                    {
                        break;
                    }
                    this.OnGotoPoint(this.cmbPoints.SelectedIndex);
                    return;

                case "picGPS":
                    if (this.cmbPoints.SelectedIndex == -1)
                    {
                        break;
                    }
                    this.OnGPSPoint(this.cmbPoints.SelectedIndex);
                    return;

                case "picInfo":
                    if (this.Feat == null)
                    {
                        break;
                    }
                    this.OnInfo();
                    return;

                case "picSave":
                    this.OnSave();
                    return;

                case "picHide":
                    this.OnHide();
                    break;

                default:
                    return;
            }
        }

        private void CmbSelectedIndexChange(object sender, EventArgs e)
        {
            this.draw.SelectedPoint(this.cmbPoints.SelectedIndex);
        }

        private void CreateControls()
        {
            this.draw = new DrawControl();
            this.draw.Map = this.OperationMap;
            this.draw.Visible = false;
            this.OperationMap.Controls.Add(this.draw);
            Assembly executingAssembly = Assembly.GetExecutingAssembly();
            Bitmap bitmap = new Bitmap(executingAssembly.GetManifestResourceStream("HiMap.MapControls.ResourceFile.save_16x16.bmp"));
            Bitmap bitmap2 = new Bitmap(executingAssembly.GetManifestResourceStream("HiMap.MapControls.ResourceFile.trash_(delete)_16x16.bmp"));
            Bitmap bitmap3 = new Bitmap(executingAssembly.GetManifestResourceStream("HiMap.MapControls.ResourceFile.zoom_in_16x16.bmp"));
            Bitmap bitmap4 = new Bitmap(executingAssembly.GetManifestResourceStream("HiMap.MapControls.ResourceFile.zoom_out_16x16.bmp"));
            this.draw.SetButton(ButtonLocation.TopLeftButton, true, Image.FromHbitmap(bitmap.GetHbitmap()), Image.FromHbitmap(bitmap.GetHbitmap()));
            this.draw.SetButton(ButtonLocation.TopRightButton, true, Image.FromHbitmap(bitmap2.GetHbitmap()), Image.FromHbitmap(bitmap2.GetHbitmap()));
            this.draw.SetButton(ButtonLocation.BottomLeftButton, true, Image.FromHbitmap(bitmap3.GetHbitmap()), Image.FromHbitmap(bitmap3.GetHbitmap()));
            this.draw.SetButton(ButtonLocation.BottomRightButton, true, Image.FromHbitmap(bitmap4.GetHbitmap()), Image.FromHbitmap(bitmap4.GetHbitmap()));
            this.draw.TopLeft_Click += new EventHandler(this.OnTopLeft_Click);
            this.draw.TopRight_Click += new EventHandler(this.OnTopRight_Click);
            this.draw.BottomLeft_Click += new EventHandler(this.OnBottomLeft_Click);
            this.draw.BottomRight_Click += new EventHandler(this.OnBottomRight_Click);
            this.draw.AfterAddPoint += new DrawControl.AfterAddPointEvent(this.OnAfterAddPointEvent);
            this.MainPan = new Panel();
            this.MainPan.BackColor = Color.Silver;
            this.MainPan.Visible = false;
            this.MainPan.Size = new Size(240, 0x16);
            this.MainPan.Location = new Point(0, 0);
            this.MainPan.MouseDown += new MouseEventHandler(this.MainPan_MouseDown);
            this.MainPan.MouseMove += new MouseEventHandler(this.MainPan_MouseMove);
            this.MainPan.MouseUp += new MouseEventHandler(this.MainPan_MouseUp);
            this.ParentForm.Controls.Add(this.MainPan);
            this.cmbPoints = new ComboBox();
            this.cmbPoints.Size = new Size(0x3a, 0x16);
            this.cmbPoints.Location = new Point(2, 1);
            this.cmbPoints.SelectedIndexChanged += new EventHandler(this.CmbSelectedIndexChange);
            PictureBox box = new PictureBox();
            box.Size = new Size(20, 20);
            box.Location = new Point(0x3f, 1);
            box.Name = "picInsert";
            box.Click += new EventHandler(this.BtnClick);
            box.SizeMode = PictureBoxSizeMode.StretchImage;
            PictureBox box2 = new PictureBox();
            box2.Size = new Size(20, 20);
            box2.Location = new Point(0x58, 1);
            box2.Name = "picDelete";
            box2.Click += new EventHandler(this.BtnClick);
            box2.SizeMode = PictureBoxSizeMode.StretchImage;
            PictureBox box3 = new PictureBox();
            box3.Size = new Size(20, 20);
            box3.Location = new Point(0x71, 1);
            box3.Name = "picSave";
            box3.Click += new EventHandler(this.BtnClick);
            box3.SizeMode = PictureBoxSizeMode.StretchImage;
            PictureBox box4 = new PictureBox();
            box4.Size = new Size(20, 20);
            box4.Location = new Point(0x8a, 1);
            box4.Name = "picHide";
            box4.Click += new EventHandler(this.BtnClick);
            box4.SizeMode = PictureBoxSizeMode.StretchImage;
            this.MainPan.Controls.Add(this.cmbPoints);
            this.MainPan.Controls.Add(box);
            this.MainPan.Controls.Add(box2);
            this.MainPan.Controls.Add(box3);
            this.MainPan.Controls.Add(box4);
            Bitmap bitmap5 = new Bitmap(executingAssembly.GetManifestResourceStream("HiMap.MapControls.ResourceFile.flag2_(add)_16x16.bmp"));
            Bitmap bitmap6 = new Bitmap(executingAssembly.GetManifestResourceStream("HiMap.MapControls.ResourceFile.flag2_(delete)_16x16.bmp"));
            new Bitmap(executingAssembly.GetManifestResourceStream("HiMap.MapControls.ResourceFile.定位点.bmp"));
            new Bitmap(executingAssembly.GetManifestResourceStream("HiMap.MapControls.ResourceFile.GPS.bmp"));
            new Bitmap(executingAssembly.GetManifestResourceStream("HiMap.MapControls.ResourceFile.information_16x16.bmp"));
            Bitmap bitmap7 = new Bitmap(executingAssembly.GetManifestResourceStream("HiMap.MapControls.ResourceFile.save_16x16.bmp"));
            Bitmap bitmap8 = new Bitmap(executingAssembly.GetManifestResourceStream("HiMap.MapControls.ResourceFile.隐藏_16x16.bmp"));
            box.Image = Image.FromHbitmap(bitmap5.GetHbitmap());
            box2.Image = Image.FromHbitmap(bitmap6.GetHbitmap());
            box3.Image = Image.FromHbitmap(bitmap7.GetHbitmap());
            box4.Image = Image.FromHbitmap(bitmap8.GetHbitmap());
        }

        public void EnvironmentUpdate()
        {
            Point point;
            this.draw.Img = this.OperationMap.MapImage;
            List<IPoint> mapPoints = new List<IPoint>();
            List<Point> displayPoints = new List<Point>();
            this.draw.DrawStop(false, out mapPoints, out displayPoints);
            this.cmbPoints.Items.Clear();
            this.cmbPoints.SelectedIndex = -1;
            for (int i = 0; i < mapPoints.Count; i++)
            {
                this.draw.CreatePoint(this.OperationMap.MapToScreen(mapPoints[i].X, mapPoints[i].Y));
            }
            if (mapPoints.Count > 0)
            {
                point = this.OperationMap.MapToScreen(mapPoints[mapPoints.Count - 1].X, mapPoints[mapPoints.Count - 1].Y);
            }
            else
            {
                point = this.OperationMap.MapToScreen((double) (this.OperationMap.Width / 2), (double) (this.OperationMap.Height / 2));
            }
            point.X -= this.draw.Width / 2;
            point.Y -= this.draw.Height / 2;
            this.draw.Location = point;
        }

        private PicType GetPicType()
        {
            PicType point = PicType.Point;
            IFeatureClass class2 = null;
            if (this._Layer != null)
            {
                class2 = (IFeatureClass) this._Layer.Class;
            }
            else
            {
                class2 = this._isEditFeature.Class;
            }
            switch (class2.GeometryType)
            {
                case GeometryType.Point:
                    return PicType.Point;

                case GeometryType.MultiPoint:
                    return PicType.MultiPoint;

                case GeometryType.Polyline:
                    return PicType.Polyline;

                case GeometryType.Polygon:
                    return PicType.Polygon;
            }
            return point;
        }

        void IEditEnvironment.Hide()
        {
            this.OnHide();
        }

        void IEditEnvironment.Show()
        {
            if ((this._Layer == null) && (this._isEditFeature == null))
            {
                this.OnHide();
            }
            else
            {
                if (this._isEditFeature == null)
                {
                    this.state = State.Create;
                }
                else
                {
                    this.state = State.Edit;
                }
                this.MainPan.BringToFront();
                this.MainPan.Location = this._Location;
                this.MainPan.Visible = true;
                this.draw.DrawType = this.GetPicType();
                if (this.state == State.Create)
                {
                    this.draw.Location = new Point((this.OperationMap.Width / 2) - (this.draw.Width / 2), (this.OperationMap.Height / 2) - (this.draw.Height / 2));
                    this.draw.Show(this.draw.Location);
                }
                else
                {
                    this.draw.isEditFeature = this._isEditFeature;
                }
                this.draw.BringToFront();
                this.draw.Visible = true;
            }
        }

        private void MainPan_MouseDown(object sender, MouseEventArgs e)
        {
            this.StaX = e.X;
            this.StaY = e.Y;
            this.isMouseDown = true;
        }

        private void MainPan_MouseMove(object sender, MouseEventArgs e)
        {
            if (this.isMouseDown)
            {
                this.MainPan.Location = new Point(0, (this.MainPan.Location.Y + e.Y) - this.StaY);
            }
        }

        private void MainPan_MouseUp(object sender, MouseEventArgs e)
        {
            this.isMouseDown = false;
        }

        private void MoveDraw(double Scale)
        {
            this.OperationMap.Map.MapScale = Scale;
            this.OperationMap.MapRefresh();
        }

        private void OnAddPoint(int index)
        {
            int x = this.draw.Pts[index].X;
            int y = this.draw.Pts[index].Y;
            x -= 0x10;
            y -= 0x10;
            this.draw.InsertPoint(index, x, y);
            this.OnSettingCmbSelected(index - 1);
        }

        private void OnAfterAddPointEvent(IPoint MapPoint, Point DisplayPoint)
        {
            this.cmbPoints.Items.Add(this.draw.Pts.Count - 1);
            this.cmbPoints.SelectedIndex = this.cmbPoints.Items.Count - 1;
        }

        private void OnBottomLeft_Click(object sender, EventArgs e)
        {
            this.MoveDraw(this.OperationMap.Map.MapScale / 2);
        }

        private void OnBottomRight_Click(object sender, EventArgs e)
        {
            this.MoveDraw(this.OperationMap.Map.MapScale * 2);
        }

        private void OnDeletePoint(int index)
        {
            this.draw.DeletePoint(index);
            this.OnSettingCmbSelected(index - 1);
            this.MePic.Draw();
        }

        private void OnGotoPoint(int index)
        {
            FrmXY mxy = new FrmXY();
            mxy.ShowDialog();
            double x = mxy.X;
            double y = mxy.Y;
            if ((x != 0) && (y != 0))
            {
                this.draw.MovePoint(index, x, y);
            }
        }

        private void OnGPSPoint(int index)
        {
            if (this._GPSPoint == null)
            {
                MessageBox.Show(Setup.GetInfo("EditEnvironmentClassMessage1"));
            }
            else
            {
                this.draw.MovePoint(index, this._GPSPoint.X, this._GPSPoint.Y);
            }
        }

        private void OnHide()
        {
            List<IPoint> mapPoints = new List<IPoint>();
            List<Point> displayPoints = new List<Point>();
            this.draw.DrawStop(false, out mapPoints, out displayPoints);
            this.draw.Visible = false;
            this.MainPan.Visible = false;
            this.cmbPoints.Items.Clear();
            mapPoints.Clear();
            displayPoints.Clear();
            this.draw.ClearDraw();
        }

        private void OnInfo()
        {
            FrmInfo info = new FrmInfo(true);
            info.LoadData(this.Feat);
            info.ShowDialog();
        }

        private void OnSave()
        {
            if (this.state == State.Create)
            {
                this.OnTopLeft_Click(null, null);
            }
        }

        private void OnSettingCmbSelected(int index)
        {
            try
            {
                this.cmbPoints.Items.Clear();
                for (int i = 0; i < this.draw.Pts.Count; i++)
                {
                    this.cmbPoints.Items.Add(i);
                }
                this.cmbPoints.SelectedIndex = index;
                if (this.cmbPoints.SelectedIndex == -1)
                {
                    this.cmbPoints.SelectedIndex = 0;
                }
            }
            catch
            {
            }
        }

        private void OnTopLeft_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show(Setup.GetInfo("ToolEditMessage2"), Setup.GetInfo("ToolEditMessage1"), MessageBoxButtons.YesNo, MessageBoxIcon.None, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
            {
                List<IPoint> mapPoints;
                List<Point> displayPoints;
                this.draw.DrawStop(true, out mapPoints, out displayPoints);
                this.SaveData(mapPoints);
                MessageBox.Show(Setup.GetInfo("ToolEditMessage4"));
                this.OnHide();
                if (this._isEditFeature != null)
                {
                    this.OperationMap.SelectedFeature = null;
                }
                this.OperationMap.MapRefresh();
            }
        }

        private void OnTopRight_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show(Setup.GetInfo("ToolEditMessage3"), Setup.GetInfo("ToolEditMessage1"), MessageBoxButtons.YesNo, MessageBoxIcon.None, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
            {
                List<IPoint> mapPoints;
                List<Point> displayPoints;
                this.draw.DrawStop(false, out mapPoints, out displayPoints);
                this.cmbPoints.Items.Clear();
                this.cmbPoints.SelectedIndex = -1;
                MessageBox.Show(Setup.GetInfo("ToolEditMessage5"));
                this.OnHide();
            }
        }

        private void SaveData(List<IPoint> pts)
        {
            IFeature feat = null;
            IGeometry geometry = null;
            feat = this.Feat;
            switch (feat.Class.GeometryType)
            {
                case GeometryType.NotGeometry:
                    this.draw.DrawType = PicType.Null;
                    break;

                case GeometryType.Point:
                {
                    IPoint point2 = new PointClass();
                    point2.X = pts[0].X;
                    point2.Y = pts[0].Y;
                    geometry = point2;
                    break;
                }
                case GeometryType.MultiPoint:
                {
                    IMultiPoint point = new MultiPointClass();
                    IGeometryCollection geometrys = point;
                    for (int i = 0; i < pts.Count; i++)
                    {
                        geometrys.AddGeometry(pts[i]);
                    }
                    geometry = point;
                    break;
                }
                case GeometryType.Polyline:
                {
                    IPolyline polyline = new PolylineClass();
                    IPointCollection points = polyline;
                    for (int j = 0; j < pts.Count; j++)
                    {
                        points.AddPoint(pts[j]);
                    }
                    geometry = polyline;
                    break;
                }
                case GeometryType.Polygon:
                {
                    IPolygon polygon = new PolygonClass();
                    IPointCollection points2 = polygon;
                    for (int k = 0; k < pts.Count; k++)
                    {
                        points2.AddPoint(pts[k]);
                    }
                    geometry = polygon;
                    break;
                }
                case GeometryType.Envelope:
                    this.draw.DrawType = PicType.Null;
                    break;
            }
            feat.Shape = geometry;
            feat.Save();
        }

        IPoint IEditEnvironment.GPSPoint
        {
            get
            {
                return this._GPSPoint;
            }
            set
            {
                this._GPSPoint = value;
            }
        }

        IFeature IEditEnvironment.isEditFeature
        {
            get
            {
                return this._isEditFeature;
            }
            set
            {
                this._isEditFeature = value;
            }
        }

        IFeatureLayer IEditEnvironment.Layer
        {
            get
            {
                return this._Layer;
            }
            set
            {
                this._Layer = value;
            }
        }

        Point IEditEnvironment.Location
        {
            get
            {
                return this._Location;
            }
            set
            {
                this._Location = value;
            }
        }

        private State state
        {
            get
            {
                return this._state;
            }
            set
            {
                this._state = value;
                if (value == State.Create)
                {
                    this.Feat = ((IFeatureClass) this._Layer.Class).CreateFeature();
                }
                else
                {
                    this.Feat = this._isEditFeature;
                }
            }
        }

        private enum State
        {
            Create,
            Edit
        }
    }
}

